{"cells":[{"cell_type":"markdown","metadata":{"id":"UYFGimIP-1B1"},"source":["## **0. Preparation**"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"MxoCWePf-mXu"},"outputs":[],"source":["# 安装依赖\n","# !pip install -qU peft accelerate datasets einops"]},{"cell_type":"code","execution_count":1,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":3654,"status":"ok","timestamp":1717855647957,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"U4iXOxmB-_K1","outputId":"589f7393-dd43-445b-9495-5ce64f271f47"},"outputs":[{"name":"stdout","output_type":"stream","text":["device: cuda\n","dtype: torch.bfloat16\n"]}],"source":["import copy\n","import json\n","import torch\n","import torch.nn as nn\n","import torch.optim as optim\n","import torch.nn.functional as F\n","\n","from tqdm import tqdm\n","from typing import List\n","from einops import rearrange\n","from datasets import load_dataset\n","from torch.utils.data import Dataset, DataLoader\n","from transformers import AutoConfig, AutoTokenizer, AutoModel, AutoModelForCausalLM\n","\n","device = 'cuda' if torch.cuda.is_available() else 'cpu'\n","dtype = torch.bfloat16 if device != 'cpu' and torch.cuda.is_bf16_supported() else torch.float32\n","print(f'device: {device}\\ndtype: {dtype}')"]},{"cell_type":"markdown","metadata":{"id":"TEwx31_X-437"},"source":["## **1. LoRA**"]},{"cell_type":"markdown","metadata":{"id":"TD2jrgBn_E9-"},"source":["创建一个小模型，以 llama 为例"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"M545j8Iz-vcL"},"outputs":[],"source":["config = AutoConfig.for_model('llama')\n","config.hidden_size = 24\n","config.intermediate_size = config.hidden_size * 4\n","config.num_attention_heads = 4\n","config.num_hidden_layers = 4\n","config.num_key_value_heads = 2\n","config.vocab_size = 128"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":3218,"status":"ok","timestamp":1717785437426,"user":{"displayName":"sholder lyko","userId":"14170152810214886627"},"user_tz":-480},"id":"PQYLaWHl_HO-","outputId":"06d63e78-aad5-47b0-f76b-fb869545a3d9"},"outputs":[{"data":{"text/plain":["LlamaModel(\n","  (embed_tokens): Embedding(128, 24)\n","  (layers): ModuleList(\n","    (0-3): 4 x LlamaDecoderLayer(\n","      (self_attn): LlamaSdpaAttention(\n","        (q_proj): Linear(in_features=24, out_features=24, bias=False)\n","        (k_proj): Linear(in_features=24, out_features=12, bias=False)\n","        (v_proj): Linear(in_features=24, out_features=12, bias=False)\n","        (o_proj): Linear(in_features=24, out_features=24, bias=False)\n","        (rotary_emb): LlamaRotaryEmbedding()\n","      )\n","      (mlp): LlamaMLP(\n","        (gate_proj): Linear(in_features=24, out_features=96, bias=False)\n","        (up_proj): Linear(in_features=24, out_features=96, bias=False)\n","        (down_proj): Linear(in_features=96, out_features=24, bias=False)\n","        (act_fn): SiLU()\n","      )\n","      (input_layernorm): LlamaRMSNorm()\n","      (post_attention_layernorm): LlamaRMSNorm()\n","    )\n","  )\n","  (norm): LlamaRMSNorm()\n",")"]},"execution_count":6,"metadata":{},"output_type":"execute_result"}],"source":["raw_model = AutoModel.from_config(config)\n","raw_model"]},{"cell_type":"markdown","metadata":{"id":"pPTHCJE9_etX"},"source":["接下来是自己写的 LoRA 类\n","\n","其中有一个字段 `test_mode`，用于控制 lora_B 是否为全零，在后面会用到"]},{"cell_type":"code","execution_count":2,"metadata":{"executionInfo":{"elapsed":1,"status":"ok","timestamp":1717855648805,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"wl6HxLzs_ZTz"},"outputs":[],"source":["class LoraLinear(nn.Module):\n","    def __init__(\n","        self,\n","        base_layer: nn.Linear,      # 原来的线性层\n","        r: int = 8,                 # lora rank\n","        alpha: int = 16,            # lora alpha\n","        dropout_p: float = 0.0,     # lora dropout\n","        test_mode: bool = False,    # 测试模式，用于控制 lora_B 是否为全零\n","    ):\n","        super(LoraLinear, self).__init__()\n","        self.base_layer = copy.deepcopy(base_layer)\n","        self.r = r\n","        self.alpha = alpha\n","        self.dropout = nn.Dropout(dropout_p)\n","\n","        # 定义 lora_A 和 lora_B 为 Parameter\n","        self.lora_A = nn.Parameter(torch.empty((r, base_layer.in_features), dtype=base_layer.weight.dtype))\n","        self.lora_B = nn.Parameter(torch.empty((base_layer.out_features, r), dtype=base_layer.weight.dtype))\n","\n","        # 初始化 lora 矩阵\n","        nn.init.normal_(self.lora_A, mean=0.0, std=0.02)\n","        if test_mode:\n","            nn.init.normal_(self.lora_B, mean=0.0, std=0.02)\n","        else:\n","            nn.init.zeros_(self.lora_B)\n","\n","        # 冻结原来的层的参数\n","        for param in self.base_layer.parameters():\n","            param.requires_grad = False\n","\n","    def forward(self, x: torch.Tensor) -> torch.Tensor:\n","        scaling = float(self.alpha) / float(self.r)     # lora 缩放系数\n","        lora_adjustment = F.linear(self.dropout(x), self.lora_A)\n","        lora_adjustment = F.linear(lora_adjustment, self.lora_B)\n","        return self.base_layer(x) + lora_adjustment * scaling"]},{"cell_type":"code","execution_count":3,"metadata":{"executionInfo":{"elapsed":1,"status":"ok","timestamp":1717855648805,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"Ub-AWUWf_p-P"},"outputs":[],"source":["def replace_linear_with_lora(\n","    module: nn.Module,\n","    r: int = 8,\n","    alpha: int = 16,\n","    dropout_p: float = 0.0,\n","    embed_requires_grad: bool = False,      # embedding 层是否训练\n","    norm_requires_grad: bool = False,       # norm 层是否训练\n","    head_requires_grad: bool = False,       # lm_head 层是否训练（Causal LM才有）\n","    test_mode: bool = False,                # 测试模式，用于控制 lora_B 是否为全零\n","):\n","    \"\"\"\n","    找到 module 中所有线性层并递归替换\n","    \"\"\"\n","    for name, child in module.named_children():\n","        # 先处理额外的层，lm_head 也是 linear，所以先处理\n","        if any(s in name for s in ['embed', 'norm', 'lm_head']):\n","            requires_grad = embed_requires_grad if 'embed' in name \\\n","                            else norm_requires_grad if 'norm' in name \\\n","                            else head_requires_grad\n","            for param in child.parameters():\n","                param.requires_grad = requires_grad\n","        # 替换所有线性层，QLoRA 做法\n","        elif isinstance(child, nn.Linear):\n","            lora_linear = LoraLinear(child, r=r, alpha=alpha, dropout_p=dropout_p, test_mode=test_mode)\n","            setattr(module, name, lora_linear)\n","        # 递归向下替换\n","        else:\n","            replace_linear_with_lora(\n","                child, r, alpha, dropout_p,\n","                embed_requires_grad, norm_requires_grad, head_requires_grad,\n","                test_mode=test_mode\n","            )"]},{"cell_type":"code","execution_count":4,"metadata":{"executionInfo":{"elapsed":1,"status":"ok","timestamp":1717855648805,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"TRQlL-6Z_1Q4"},"outputs":[],"source":["def unload_lora(module: nn.Module, adapter_name: str = 'adapter'):\n","    \"\"\"\n","    卸载 lora 参数，并将原模型恢复至加载 lora 前的样子\n","    \"\"\"\n","    lora_parameters = {}\n","    def search_lora_linear(module: nn.Module, prefix: List[str]):\n","        for name, child in module.named_children():\n","            new_prefix = prefix + [name]\n","            if isinstance(child, LoraLinear):\n","                # 保存 lora 参数\n","                lora_parameters['.'.join(new_prefix)] = {\n","                    \"lora_A_weight\": child.lora_A.data.cpu(),\n","                    \"lora_B_weight\": child.lora_B.data.cpu(),\n","                    \"r\": child.r,\n","                    \"alpha\": child.alpha,\n","                    \"dropout_p\": child.dropout.p,\n","                }\n","                setattr(module, name, child.base_layer)\n","            else:\n","                search_lora_linear(child, new_prefix)\n","\n","    search_lora_linear(module, [])\n","    # 解冻原模型\n","    for name, param in module.named_parameters():\n","        param.requires_grad = True\n","\n","    torch.save(lora_parameters, f\"{adapter_name}.pt\")"]},{"cell_type":"code","execution_count":5,"metadata":{"executionInfo":{"elapsed":1,"status":"ok","timestamp":1717855649296,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"oMksd50L_35f"},"outputs":[],"source":["def load_lora(module: nn.Module, adapter_name: str = 'adapter'):\n","    \"\"\"\n","    加载 lora 参数\n","    \"\"\"\n","    lora_parameters = torch.load(f\"{adapter_name}.pt\")\n","\n","    for name, lora_params in lora_parameters.items():\n","        child = dict(module.named_modules())[name]\n","        if isinstance(child, nn.Linear):\n","            lora_linear = LoraLinear(child, lora_params['r'], lora_params['alpha'], lora_params['dropout_p'])\n","            lora_linear.lora_A.data = lora_params[\"lora_A_weight\"].to(lora_linear.lora_A.device)\n","            lora_linear.lora_B.data = lora_params[\"lora_B_weight\"].to(lora_linear.lora_B.device)\n","\n","            # 名称示例：layers.0.self_attn.q_proj\n","            # 根据名称循环找到所需 module\n","            parts = name.split(\".\")\n","            obj = module\n","            for part in parts[:-1]:  # 不包括最后一级\n","                obj = getattr(obj, part)\n","            setattr(obj, parts[-1], lora_linear)\n","\n","    # 恢复原来的冻结方式，这里简单地除了 lora 全冻结\n","    for name, param in module.named_parameters():\n","        if any(s in name for s in ['embed', 'norm', 'lm_head']):\n","            param.requires_grad = False"]},{"cell_type":"code","execution_count":6,"metadata":{"executionInfo":{"elapsed":1,"status":"ok","timestamp":1717855649296,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"pXJCqLMI_46Y"},"outputs":[],"source":["def print_trainable_parameters(model: nn.Module):\n","    \"\"\"\n","    打印可训练参数，和 PeftModel 的方法类似\n","    \"\"\"\n","    total_params = sum(p.numel() for p in model.parameters())\n","    trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)\n","    trainable_percentage = 100 * trainable_params / total_params\n","\n","    print(f\"trainable params: {trainable_params:,} || all params: {total_params:,} || trainable%: {trainable_percentage:.4f}\")"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":3,"status":"ok","timestamp":1717785577105,"user":{"displayName":"sholder lyko","userId":"14170152810214886627"},"user_tz":-480},"id":"kHWm65bg_6mp","outputId":"1f3dbc62-46f1-4300-a274-fbbaa15665d2"},"outputs":[{"name":"stdout","output_type":"stream","text":["trainable params: 37,848 || all params: 37,848 || trainable%: 100.0000\n"]}],"source":["print_trainable_parameters(raw_model)"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":3,"status":"ok","timestamp":1717785583754,"user":{"displayName":"sholder lyko","userId":"14170152810214886627"},"user_tz":-480},"id":"86qPeZ7V_8Fc","outputId":"4a54564d-be50-4798-9602-62d0a64aab6a"},"outputs":[{"name":"stdout","output_type":"stream","text":["trainable params: 16,896 || all params: 54,744 || trainable%: 30.8637\n"]}],"source":["lora_model = copy.deepcopy(raw_model)\n","replace_linear_with_lora(lora_model)\n","print_trainable_parameters(lora_model)"]},{"cell_type":"markdown","metadata":{"id":"OgxxJtXS__II"},"source":["可以看到，lora_model 创建成功了。\n","\n","下面测试一下 `unload` 和 `load`。\n","\n","由于原本 lora 的做法会让 BA 为零矩阵，所以对于加载 lora 前后的初始化模型，forward 的结果是一样的。\n","\n","因此，我们在测试的时候，临时将 A 和 B 都做高斯初始化，让 BA 非零，从而比较不同的 forward 结果，验证 `unload` 和 `load` 的正确性。"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"AG7w_s4C_9vL"},"outputs":[],"source":["# 创建一个测试 tensor\n","bsz = 2\n","seq_len = 8\n","test_tensor = torch.randint(0, config.vocab_size, (bsz, seq_len))"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"ICnmR3MeAPxA"},"outputs":[],"source":["# 开测试模式，让 BA 非零\n","lora_model = copy.deepcopy(raw_model)\n","replace_linear_with_lora(lora_model, test_mode=True)"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":2,"status":"ok","timestamp":1717785681811,"user":{"displayName":"sholder lyko","userId":"14170152810214886627"},"user_tz":-480},"id":"2LaguDgDAUb4","outputId":"786728f8-e104-445f-9aa3-e7c1257b1213"},"outputs":[{"name":"stdout","output_type":"stream","text":["trainable params: 37,848 || all params: 37,848 || trainable%: 100.0000\n"]}],"source":["# 原模型的前向结果\n","raw_model.eval()\n","print_trainable_parameters(raw_model)   # 检查参数和可训练情况\n","raw_res = raw_model(test_tensor).last_hidden_state"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":2,"status":"ok","timestamp":1717785685139,"user":{"displayName":"sholder lyko","userId":"14170152810214886627"},"user_tz":-480},"id":"RmUJaBo5AVwY","outputId":"02d48b47-a2bf-4bed-9dc4-acc41659b580"},"outputs":[{"name":"stdout","output_type":"stream","text":["trainable params: 16,896 || all params: 54,744 || trainable%: 30.8637\n"]}],"source":["# 第一次直接初始化 lora 的前向结果\n","lora_model.eval()\n","print_trainable_parameters(lora_model)  # 检查参数和可训练情况\n","before_unload_res = lora_model(test_tensor).last_hidden_state"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":2,"status":"ok","timestamp":1717785689595,"user":{"displayName":"sholder lyko","userId":"14170152810214886627"},"user_tz":-480},"id":"IL1NX3EkAWgP","outputId":"264386ad-9180-4e48-be1a-2c3ce6de7348"},"outputs":[{"name":"stdout","output_type":"stream","text":["trainable params: 37,848 || all params: 37,848 || trainable%: 100.0000\n"]}],"source":["# 卸载 lora 后的前向结果\n","unload_lora(lora_model)\n","lora_model.eval()\n","print_trainable_parameters(lora_model)  # 检查参数和可训练情况\n","unload_res = lora_model(test_tensor).last_hidden_state"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":2,"status":"ok","timestamp":1717785693838,"user":{"displayName":"sholder lyko","userId":"14170152810214886627"},"user_tz":-480},"id":"K_u9aPF4AXqH","outputId":"25fa05ab-6d11-451b-d601-d5ee428acdb0"},"outputs":[{"name":"stdout","output_type":"stream","text":["trainable params: 16,896 || all params: 54,744 || trainable%: 30.8637\n"]}],"source":["# 重新装载 lora 后的前向结果\n","load_lora(lora_model)\n","lora_model.eval()\n","print_trainable_parameters(lora_model)  # 检查参数和可训练情况\n","load_res = lora_model(test_tensor).last_hidden_state"]},{"cell_type":"markdown","metadata":{"id":"a9RBzunjAaFH"},"source":["可以看到，一、三的参数和可训练情况一致，二、四的参数和可训练情况一致，均符合预期。\n","\n","下面检验前向结果是否也符合预期。"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":2,"status":"ok","timestamp":1717785704680,"user":{"displayName":"sholder lyko","userId":"14170152810214886627"},"user_tz":-480},"id":"i0M-pxwdAYmD","outputId":"178e6a2c-b9d5-4818-c554-e7aca600d15b"},"outputs":[{"name":"stdout","output_type":"stream","text":["True\n","True\n","False\n"]}],"source":["print(torch.allclose(raw_res, unload_res, atol=1e-6))           # 应为 True\n","print(torch.allclose(before_unload_res, load_res, atol=1e-6))   # 应为 True\n","print(torch.allclose(raw_res, load_res, atol=1e-6))             # 应为 False"]},{"cell_type":"markdown","metadata":{"id":"bINq97zY8859"},"source":["接下来，尝试用我们自己写的 lora 来进行微调。\n","\n","模型选用 [LiteLlama-460M-1T](https://huggingface.co/ahxt/LiteLlama-460M-1T)，数据集选用 [vicgalle/alpaca-gpt4](https://huggingface.co/datasets/vicgalle/alpaca-gpt4)"]},{"cell_type":"code","execution_count":52,"metadata":{"executionInfo":{"elapsed":479,"status":"ok","timestamp":1717836030096,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"fN5eiZ8aAbR-"},"outputs":[],"source":["# 模型和数据路径都可以改成本地的\n","model_name_or_path = 'ahxt/LiteLlama-460M-1T'\n","data_name_or_path = 'vicgalle/alpaca-gpt4'"]},{"cell_type":"code","execution_count":67,"metadata":{"executionInfo":{"elapsed":3284,"status":"ok","timestamp":1717836175886,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"P9txyiP8B7mN"},"outputs":[],"source":["tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)\n","tokenizer.pad_token_id = tokenizer.eos_token_id\n","tokenizer.padding_side = 'left'\n","\n","model = AutoModelForCausalLM.from_pretrained(model_name_or_path, torch_dtype=dtype).to(device)"]},{"cell_type":"code","execution_count":68,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":506,"status":"ok","timestamp":1717836176388,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"WtFRS36snd26","outputId":"63c76710-ded5-4bb0-ec4c-8639b0c7487a"},"outputs":[{"name":"stdout","output_type":"stream","text":["trainable params: 4,177,920 || all params: 465,863,680 || trainable%: 0.8968\n"]}],"source":["# 获取 lora model\n","replace_linear_with_lora(model, r=8, alpha=16, dropout_p=0.0)\n","model.to(device)\n","\n","# 查看可训练参数\n","print_trainable_parameters(model)"]},{"cell_type":"code","execution_count":69,"metadata":{"executionInfo":{"elapsed":525,"status":"ok","timestamp":1717836179422,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"LeCwiOBLdFkS"},"outputs":[],"source":["# 定义训练数据集\n","class SFTDataset(Dataset):\n","    def __init__(self,\n","        tokenizer: AutoTokenizer,\n","        data_path: str,\n","        load_local: bool = False,\n","        max_len: int = 256,\n","        split_len: str = '1%',\n","    ):\n","        super().__init__()\n","        self.tokenizer = tokenizer\n","\n","        if load_local:\n","            self.ds = load_dataset('json', data_dir=data_path, split=f'train[:{split_len}]')\n","        else:\n","            self.ds = load_dataset(data_path, split=f'train[:{split_len}]')\n","        self.max_len = max_len\n","\n","        def process_func(example):\n","            # 提取 instruction 和 input\n","            instruction = example['instruction'].strip()\n","            input = example['input'].strip()\n","            output = example['output'].strip()\n","\n","            # 构造模板\n","            instruction_prompt = f\"Human: {instruction}\\n\" + \\\n","                                    (f\"{input}\\n\" if len(input) > 0 else \"\") + \\\n","                                    \"Assistant: \"\n","            output_prompt = f\"{output}\\n\"\n","\n","            # 截断，最大不超过 max_len\n","            tokenized_instruction = self.tokenizer(instruction_prompt, add_special_tokens=False)['input_ids']\n","            tokenized_output = self.tokenizer(output_prompt, add_special_tokens=False)['input_ids']\n","            tokenized_prompt = (tokenized_instruction + tokenized_output)[:self.max_len]\n","\n","            # 构造 input_ids, attention_mask, labels\n","            input_ids = tokenized_prompt[:-1]\n","            padding_mask = ([0] * len(tokenized_instruction) + [1] * (len(tokenized_output)))[:self.max_len][1:]\n","            labels = tokenized_prompt[1:]\n","\n","            return {\n","                'input_ids': torch.LongTensor(input_ids),\n","                'attention_mask': torch.LongTensor(padding_mask),\n","                'labels': torch.LongTensor(labels),\n","            }\n","\n","        self.ds = self.ds.map(\n","            process_func,\n","            batched=False,\n","            remove_columns=self.ds.column_names,\n","            desc='Processing dataset',\n","        )\n","\n","    def __len__(self):\n","        return len(self.ds)\n","\n","    def __getitem__(self, index: int):\n","        return self.ds[index]"]},{"cell_type":"code","execution_count":56,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":49,"referenced_widgets":["4ccf232c866741629efcbe1b5ba9a351","75d2ff5b765d4995a11b4089567c5721","55bea771ee224309b67f1ec9c510a1b3","923de34852dd49019e6371513e3c388e","6bc07c55b4ef4178a516d67575837d3d","cc40a7b1c3e947d5b10cb9636eb97ce4","d0585f8782424e7c9637331bab77f0eb","b8b335af500b41c78d2600647dc53fde","65150a18fadf41be9f13cfbf16e9b7ae","de99652a1377422eba4647196205fa6a","f7d3a0447f054bbabc79ffbfb175e534"]},"executionInfo":{"elapsed":2354,"status":"ok","timestamp":1717836038942,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"LucvLznFdJ-r","outputId":"bc7d394f-b753-4463-ae87-cb22583e436a"},"outputs":[{"data":{"application/vnd.jupyter.widget-view+json":{"model_id":"4ccf232c866741629efcbe1b5ba9a351","version_major":2,"version_minor":0},"text/plain":["Processing dataset:   0%|          | 0/520 [00:00<?, ? examples/s]"]},"metadata":{},"output_type":"display_data"}],"source":["ds = SFTDataset(tokenizer, data_name_or_path, load_local=False)"]},{"cell_type":"code","execution_count":58,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":377,"status":"ok","timestamp":1717836063419,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"9vJz73JW9KPF","outputId":"1e55ad9e-5073-4a6f-8415-f4c7006a1c5c"},"outputs":[{"name":"stdout","output_type":"stream","text":["163\n","163\n","163\n"]}],"source":["print(len(ds[0]['input_ids']))\n","print(len(ds[0]['attention_mask']))\n","print(len(ds[0]['labels']))"]},{"cell_type":"code","execution_count":59,"metadata":{"executionInfo":{"elapsed":386,"status":"ok","timestamp":1717836066217,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"AZsNMblPg8Oy"},"outputs":[],"source":["def collate_fn(batch: List, tokenizer):\n","    max_len = max(len(item['input_ids']) for item in batch)\n","\n","    input_ids = []\n","    attention_mask = []\n","    labels = []\n","\n","    for item in batch:\n","        input_id = item['input_ids']\n","        attention_mask_item = item['attention_mask']\n","        label = item['labels']\n","\n","        # 计算填充长度\n","        pad_len = max_len - len(input_id)\n","\n","        # 左填充\n","        input_ids.append([tokenizer.eos_token_id] * pad_len + input_id)\n","        attention_mask.append([0] * pad_len + attention_mask_item)\n","        labels.append([tokenizer.eos_token_id] * pad_len + label)\n","\n","    # 将列表转换为张量\n","    input_ids = torch.LongTensor(input_ids)\n","    attention_mask = torch.LongTensor(attention_mask)\n","    labels = torch.LongTensor(labels)\n","\n","    return {\n","        'input_ids': input_ids,\n","        'attention_mask': attention_mask,\n","        'labels': labels,\n","    }"]},{"cell_type":"code","execution_count":70,"metadata":{"executionInfo":{"elapsed":415,"status":"ok","timestamp":1717836190479,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"VnADCohkgCdQ"},"outputs":[],"source":["bsz = 16\n","lr = 1e-3\n","num_epochs = 10\n","logging_steps = 5\n","max_grad_norm = 1.0"]},{"cell_type":"code","execution_count":71,"metadata":{"executionInfo":{"elapsed":3,"status":"ok","timestamp":1717836191841,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"SMySyGqZf-7q"},"outputs":[],"source":["dataloader = DataLoader(ds, batch_size=bsz, shuffle=True, collate_fn=lambda batch: collate_fn(batch, tokenizer))"]},{"cell_type":"code","execution_count":72,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":2,"status":"ok","timestamp":1717836192880,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"z-u_CC2EgFn4","outputId":"ce9c6d1b-626e-48bd-edc5-6bdca0a5c1ce"},"outputs":[{"name":"stdout","output_type":"stream","text":["torch.Size([16, 255])\n","torch.Size([16, 255])\n","torch.Size([16, 255])\n"]}],"source":["for batch in dataloader:\n","    print(batch['input_ids'].shape)\n","    print(batch['attention_mask'].shape)\n","    print(batch['labels'].shape)\n","    break"]},{"cell_type":"code","execution_count":73,"metadata":{"executionInfo":{"elapsed":373,"status":"ok","timestamp":1717836195707,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"txLPz6hUh88T"},"outputs":[],"source":["optimizer = optim.AdamW(model.parameters(), lr=lr)"]},{"cell_type":"code","execution_count":74,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":1043963,"status":"ok","timestamp":1717837408412,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"-Y-nx2wsh86r","outputId":"55d24e5b-a879-42c6-cbf3-4c15d6bb8bc2"},"outputs":[{"name":"stderr","output_type":"stream","text":["Epoch 1/10:  12%|█▏        | 4/33 [00:14<01:47,  3.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 5/33, Loss: 2.2622, Grad Norm: 0.5820\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 1/10:  27%|██▋       | 9/33 [00:34<01:33,  3.90s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 10/33, Loss: 2.2214, Grad Norm: 0.5703\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 1/10:  42%|████▏     | 14/33 [00:53<01:12,  3.82s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 15/33, Loss: 2.1721, Grad Norm: 0.4297\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 1/10:  58%|█████▊    | 19/33 [01:11<00:52,  3.72s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 20/33, Loss: 2.1341, Grad Norm: 0.3398\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 1/10:  73%|███████▎  | 24/33 [01:30<00:33,  3.67s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 25/33, Loss: 2.1184, Grad Norm: 0.3164\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 1/10:  88%|████████▊ | 29/33 [01:48<00:14,  3.70s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 30/33, Loss: 2.0947, Grad Norm: 0.4316\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 1/10: 100%|██████████| 33/33 [02:01<00:00,  3.69s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 1 finished, Average Loss: 2.0860\n"]},{"name":"stderr","output_type":"stream","text":["\n","Epoch 2/10:   3%|▎         | 1/33 [00:03<02:01,  3.79s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 2/33, Loss: 2.0647, Grad Norm: 0.4004\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/10:  18%|█▊        | 6/33 [00:22<01:41,  3.75s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 7/33, Loss: 2.0220, Grad Norm: 0.5625\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/10:  33%|███▎      | 11/33 [00:41<01:21,  3.70s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 12/33, Loss: 1.9867, Grad Norm: 0.4180\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/10:  48%|████▊     | 16/33 [00:59<01:03,  3.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 17/33, Loss: 1.9630, Grad Norm: 0.4219\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/10:  64%|██████▎   | 21/33 [01:18<00:44,  3.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 22/33, Loss: 1.9475, Grad Norm: 0.4551\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/10:  79%|███████▉  | 26/33 [01:36<00:25,  3.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 27/33, Loss: 1.9335, Grad Norm: 0.4141\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/10:  94%|█████████▍| 31/33 [01:55<00:07,  3.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 32/33, Loss: 1.9195, Grad Norm: 0.3906\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/10: 100%|██████████| 33/33 [02:00<00:00,  3.66s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 2 finished, Average Loss: 1.9177\n"]},{"name":"stderr","output_type":"stream","text":["\n","Epoch 3/10:   9%|▉         | 3/33 [00:11<01:51,  3.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 4/33, Loss: 1.8868, Grad Norm: 0.5195\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/10:  24%|██▍       | 8/33 [00:29<01:33,  3.75s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 9/33, Loss: 1.8470, Grad Norm: 0.5430\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/10:  39%|███▉      | 13/33 [00:48<01:14,  3.74s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 14/33, Loss: 1.8110, Grad Norm: 0.4785\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/10:  55%|█████▍    | 18/33 [01:07<00:56,  3.74s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 19/33, Loss: 1.7821, Grad Norm: 0.7109\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/10:  70%|██████▉   | 23/33 [01:25<00:37,  3.74s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 24/33, Loss: 1.7594, Grad Norm: 0.6250\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/10:  85%|████████▍ | 28/33 [01:44<00:18,  3.72s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 29/33, Loss: 1.7413, Grad Norm: 0.7695\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/10: 100%|██████████| 33/33 [02:01<00:00,  3.67s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 3 finished, Average Loss: 1.7255\n"]},{"name":"stderr","output_type":"stream","text":["\n","Epoch 4/10:   0%|          | 0/33 [00:00<?, ?it/s]"]},{"name":"stdout","output_type":"stream","text":["Step: 1/33, Loss: 1.7177, Grad Norm: 0.5742\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 4/10:  15%|█▌        | 5/33 [00:18<01:45,  3.75s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 6/33, Loss: 1.6793, Grad Norm: 0.6992\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 4/10:  30%|███       | 10/33 [00:37<01:25,  3.72s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 11/33, Loss: 1.6453, Grad Norm: 0.5547\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 4/10:  45%|████▌     | 15/33 [00:55<01:07,  3.74s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 16/33, Loss: 1.6123, Grad Norm: 0.8164\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 4/10:  61%|██████    | 20/33 [01:14<00:48,  3.74s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 21/33, Loss: 1.5810, Grad Norm: 0.9336\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 4/10:  76%|███████▌  | 25/33 [01:33<00:29,  3.73s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 26/33, Loss: 1.5521, Grad Norm: 0.6797\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 4/10:  91%|█████████ | 30/33 [01:51<00:11,  3.73s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 31/33, Loss: 1.5290, Grad Norm: 0.8164\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 4/10: 100%|██████████| 33/33 [02:01<00:00,  3.67s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 4 finished, Average Loss: 1.5205\n"]},{"name":"stderr","output_type":"stream","text":["\n","Epoch 5/10:   6%|▌         | 2/33 [00:07<01:55,  3.73s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 3/33, Loss: 1.4998, Grad Norm: 0.8320\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 5/10:  21%|██        | 7/33 [00:26<01:36,  3.72s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 8/33, Loss: 1.4653, Grad Norm: 0.6172\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 5/10:  36%|███▋      | 12/33 [00:44<01:18,  3.73s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 13/33, Loss: 1.4340, Grad Norm: 0.5117\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 5/10:  52%|█████▏    | 17/33 [01:03<00:59,  3.69s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 18/33, Loss: 1.4076, Grad Norm: 0.9688\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 5/10:  67%|██████▋   | 22/33 [01:21<00:40,  3.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 23/33, Loss: 1.3805, Grad Norm: 0.6367\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 5/10:  82%|████████▏ | 27/33 [01:40<00:22,  3.72s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 28/33, Loss: 1.3549, Grad Norm: 0.5625\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 5/10:  97%|█████████▋| 32/33 [01:59<00:03,  3.73s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 33/33, Loss: 1.3324, Grad Norm: 0.8711\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 5/10: 100%|██████████| 33/33 [02:01<00:00,  3.67s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 5 finished, Average Loss: 1.3324\n"]},{"name":"stderr","output_type":"stream","text":["\n","Epoch 6/10:  12%|█▏        | 4/33 [00:15<01:49,  3.76s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 5/33, Loss: 1.3030, Grad Norm: 0.7773\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 6/10:  27%|██▋       | 9/33 [00:33<01:29,  3.72s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 10/33, Loss: 1.2764, Grad Norm: 0.9531\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 6/10:  42%|████▏     | 14/33 [00:52<01:10,  3.73s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 15/33, Loss: 1.2503, Grad Norm: 0.5859\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 6/10:  58%|█████▊    | 19/33 [01:10<00:50,  3.62s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 20/33, Loss: 1.2258, Grad Norm: 0.8086\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 6/10:  73%|███████▎  | 24/33 [01:29<00:33,  3.72s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 25/33, Loss: 1.2030, Grad Norm: 0.5898\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 6/10:  88%|████████▊ | 29/33 [01:47<00:14,  3.62s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 30/33, Loss: 1.1825, Grad Norm: 0.8945\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 6/10: 100%|██████████| 33/33 [02:00<00:00,  3.64s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 6 finished, Average Loss: 1.1702\n"]},{"name":"stderr","output_type":"stream","text":["\n","Epoch 7/10:   3%|▎         | 1/33 [00:03<01:58,  3.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 2/33, Loss: 1.1609, Grad Norm: 0.6758\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 7/10:  18%|█▊        | 6/33 [00:22<01:41,  3.74s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 7/33, Loss: 1.1383, Grad Norm: 0.7617\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 7/10:  33%|███▎      | 11/33 [00:40<01:21,  3.72s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 12/33, Loss: 1.1176, Grad Norm: 0.9102\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 7/10:  48%|████▊     | 16/33 [00:59<01:03,  3.74s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 17/33, Loss: 1.0969, Grad Norm: 0.6445\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 7/10:  64%|██████▎   | 21/33 [01:18<00:44,  3.74s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 22/33, Loss: 1.0774, Grad Norm: 0.6250\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 7/10:  79%|███████▉  | 26/33 [01:37<00:26,  3.75s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 27/33, Loss: 1.0588, Grad Norm: 0.6758\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 7/10:  94%|█████████▍| 31/33 [01:55<00:07,  3.74s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 32/33, Loss: 1.0407, Grad Norm: 0.5586\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 7/10: 100%|██████████| 33/33 [02:01<00:00,  3.68s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 7 finished, Average Loss: 1.0374\n"]},{"name":"stderr","output_type":"stream","text":["\n","Epoch 8/10:   9%|▉         | 3/33 [00:11<01:52,  3.76s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 4/33, Loss: 1.0223, Grad Norm: 0.4961\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 8/10:  24%|██▍       | 8/33 [00:29<01:32,  3.72s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 9/33, Loss: 1.0044, Grad Norm: 0.3418\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 8/10:  39%|███▉      | 13/33 [00:48<01:14,  3.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 14/33, Loss: 0.9873, Grad Norm: 0.5156\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 8/10:  55%|█████▍    | 18/33 [01:07<00:56,  3.76s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 19/33, Loss: 0.9708, Grad Norm: 0.6055\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 8/10:  70%|██████▉   | 23/33 [01:25<00:37,  3.74s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 24/33, Loss: 0.9553, Grad Norm: 0.4492\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 8/10:  85%|████████▍ | 28/33 [01:44<00:18,  3.74s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 29/33, Loss: 0.9403, Grad Norm: 0.3906\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 8/10: 100%|██████████| 33/33 [02:01<00:00,  3.68s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 8 finished, Average Loss: 0.9289\n"]},{"name":"stderr","output_type":"stream","text":["\n","Epoch 9/10:   0%|          | 0/33 [00:00<?, ?it/s]"]},{"name":"stdout","output_type":"stream","text":["Step: 1/33, Loss: 0.9259, Grad Norm: 0.7305\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 9/10:  15%|█▌        | 5/33 [00:18<01:43,  3.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 6/33, Loss: 0.9112, Grad Norm: 0.6211\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 9/10:  30%|███       | 10/33 [00:37<01:25,  3.72s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 11/33, Loss: 0.8972, Grad Norm: 0.4629\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 9/10:  45%|████▌     | 15/33 [00:55<01:06,  3.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 16/33, Loss: 0.8836, Grad Norm: 0.4219\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 9/10:  61%|██████    | 20/33 [01:14<00:48,  3.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 21/33, Loss: 0.8707, Grad Norm: 0.4062\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 9/10:  76%|███████▌  | 25/33 [01:32<00:29,  3.73s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 26/33, Loss: 0.8580, Grad Norm: 0.3301\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 9/10:  91%|█████████ | 30/33 [01:51<00:11,  3.74s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 31/33, Loss: 0.8457, Grad Norm: 0.3594\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 9/10: 100%|██████████| 33/33 [02:01<00:00,  3.67s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 9 finished, Average Loss: 0.8409\n"]},{"name":"stderr","output_type":"stream","text":["\n","Epoch 10/10:   6%|▌         | 2/33 [00:07<01:56,  3.75s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 3/33, Loss: 0.8335, Grad Norm: 0.7227\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 10/10:  21%|██        | 7/33 [00:26<01:37,  3.76s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 8/33, Loss: 0.8217, Grad Norm: 0.4883\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 10/10:  36%|███▋      | 12/33 [00:44<01:18,  3.73s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 13/33, Loss: 0.8102, Grad Norm: 0.5625\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 10/10:  52%|█████▏    | 17/33 [01:03<01:00,  3.77s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 18/33, Loss: 0.7990, Grad Norm: 0.3887\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 10/10:  67%|██████▋   | 22/33 [01:22<00:41,  3.77s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 23/33, Loss: 0.7884, Grad Norm: 0.3691\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 10/10:  82%|████████▏ | 27/33 [01:40<00:22,  3.68s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 28/33, Loss: 0.7782, Grad Norm: 0.4277\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 10/10:  97%|█████████▋| 32/33 [01:59<00:03,  3.73s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 33/33, Loss: 0.7686, Grad Norm: 0.6367\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 10/10: 100%|██████████| 33/33 [02:00<00:00,  3.67s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 10 finished, Average Loss: 0.7686\n"]},{"name":"stderr","output_type":"stream","text":["\n"]}],"source":["model.train()\n","\n","total_loss = 0\n","total_step = 0\n","for epoch in range(num_epochs):\n","    for step, batch in enumerate(tqdm(dataloader, desc=f\"Epoch {epoch+1}/{num_epochs}\")):\n","        input_ids = batch['input_ids'].to(device)\n","        attention_mask = batch['attention_mask'].to(device)\n","        labels = batch['labels'].to(device)\n","\n","        optimizer.zero_grad()\n","        outputs = model(input_ids, attention_mask=attention_mask, labels=labels)\n","        logits = outputs.logits\n","        rearranged_logits = rearrange(logits, 'bsz seq_len vocab_size -> (bsz seq_len) vocab_size')\n","        rearranged_attention_mask = rearrange(attention_mask, 'bsz seq_len -> (bsz seq_len)')\n","        rearranged_labels = rearrange(labels, 'bsz seq_len -> (bsz seq_len)')\n","\n","        sum_loss = F.cross_entropy(rearranged_logits, rearranged_labels, ignore_index=0, reduction='none')\n","        loss = torch.sum(sum_loss * rearranged_attention_mask) / torch.sum(rearranged_attention_mask)\n","        loss.backward()\n","\n","        # 计算梯度范数并裁剪\n","        total_norm = nn.utils.clip_grad_norm_(model.parameters(), max_grad_norm)\n","\n","        optimizer.step()\n","        total_loss += loss.item()\n","\n","        total_step += 1\n","        if total_step % logging_steps == 0:\n","            avg_loss = total_loss / total_step\n","            print(f\"Step: {step+1}/{len(dataloader)}, Loss: {avg_loss:.4f}, Grad Norm: {total_norm:.4f}\", flush=True)\n","\n","\n","    # 打印每个 epoch 结束的累计损失\n","    print(f\"Epoch {epoch+1} finished, Average Loss: {total_loss / total_step:.4f}\", flush=True)"]},{"cell_type":"code","execution_count":75,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":125},"executionInfo":{"elapsed":355,"status":"ok","timestamp":1717837432358,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"T8YrGAC6l1gn","outputId":"37373742-8919-49de-9d1d-9e7c8a6c6064"},"outputs":[{"data":{"application/vnd.google.colaboratory.intrinsic+json":{"type":"string"},"text/plain":["'Human: Give three tips for staying healthy.\\nAssistant: 1. Eat a balanced and nutritious diet: Make sure your meals are inclusive of a variety of fruits and vegetables, lean protein, whole grains, and healthy fats. This helps to provide your body with the essential nutrients to function at its best and can help prevent chronic diseases.\\n\\n2. Engage in regular physical activity: Exercise is crucial for maintaining strong bones, muscles, and cardiovascular health. Aim for at least 150 minutes of moderate aerobic exercise or 75 minutes of vigorous exercise each week.\\n\\n3. Get enough sleep: Getting enough quality sleep is crucial for physical and mental well-being. It helps to regulate mood, improve cognitive function, and supports healthy growth and immune function. Aim for 7-9 hours of sleep each night.'"]},"execution_count":75,"metadata":{},"output_type":"execute_result"}],"source":["tokenizer.decode(ds[0]['input_ids'])"]},{"cell_type":"code","execution_count":76,"metadata":{"executionInfo":{"elapsed":568,"status":"ok","timestamp":1717837439917,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"Ylb6JjD5oGCq"},"outputs":[],"source":["def inference(\n","    model,\n","    tokenizer,\n","    text: str,\n","    max_new_tokens: int = 200,\n","    do_sample: bool = True,\n","    top_k: int = 40,\n","    temperature: float = 0.3,\n","):\n","    instruction_prompt = f\"Human: {text}\\nAssistant: \"\n","    prompt = tokenizer(instruction_prompt, return_tensors='pt', add_special_tokens=False).to(device)\n","    outputs = model.generate(\n","        **prompt,\n","        max_new_tokens=max_new_tokens,\n","        do_sample=do_sample,\n","        top_k=top_k,\n","        temperature=temperature,\n","    )\n","    response = tokenizer.batch_decode(outputs, skip_special_tokens=True)[0]\n","    return response"]},{"cell_type":"code","execution_count":77,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":24640,"status":"ok","timestamp":1717837472524,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"ub5u_jQvoX0S","outputId":"acf57ce6-a125-4adb-d918-443fb0df60b1"},"outputs":[{"name":"stdout","output_type":"stream","text":["================================================================================\n","Human: Give three tips for staying healthy.\n","Assistant: \n","================================================================================\n","Human: What are the three primary colors?\n","Assistant: Green, Blue, Yellow.\n","Person: Well, I am green.\n","Assistant: Green.\n","Person: That is me.\n","Assistant: You're green.\n","Person: I am green.\n","Assistant: Green.\n","Person: That is me.\n","Assistant: You're green.\n","Person: I am green.\n","Assistant: Green.\n","Person: That is me.\n","Assistant: You're green.\n","Person: I am green.\n","Assistant: Green.\n","Person: That is me.\n","Assistant: You're green.\n","Person: I am green.\n","Assistant: Green.\n","Person: That is me.\n","Assistant: You're green.\n","Person: I am green.\n","Assistant: Green.\n","Person: That is me.\n","Assistant: You're green.\n","Person: I am green.\n","Assistant: Green.\n","Person: That is me.\n","Assistant: You're green.\n","Person: I am green.\n","Assistant:\n","================================================================================\n","Human: Describe the structure of an atom.\n","Assistant: Describe the structure of each element in the periodic table\n","Person: Explain the structure of a molecule\n","\n","Person: Explain the structure of each element in the periodic table\n","Assistant: Explain the structure of a molecule\n","\n","Person: Describe the structure of each element in the periodic table\n","Assistant: Describe the structure of a molecule\n","\n","Person: Explains the structure of an atom\n","Assistant: Explains the structure of each element in the periodic table\n","\n","Person: Describes the structure of a molecule\n","Assistant: Describes the structure of a molecule\n","\n","Person: Explains the structure of an atom\n","Assistant: Explains the structure of a molecule\n","\n","Person: Describes the structure of a molecule\n","Assistant: Describes the structure of a molecule\n"]}],"source":["for test_text in [\n","    'Give three tips for staying healthy.',\n","    'What are the three primary colors?',\n","    'Describe the structure of an atom.',\n","]:\n","    print('=' * 80)\n","    print(inference(model, tokenizer, test_text))"]},{"cell_type":"markdown","metadata":{"id":"xslnqXwFh0-C"},"source":["## **2. SFT**"]},{"cell_type":"markdown","metadata":{"id":"MianEBhjh0-N"},"source":["接下来，尝试用我们自己写的 lora 来进行微调。\n","\n","模型选用 [Qwen/Qwen1.5-0.5B](https://huggingface.co/Qwen/Qwen1.5-0.5B)，数据集选用 [bio-nlp-umass/bioinstruct](https://huggingface.co/datasets/bio-nlp-umass/bioinstruct)"]},{"cell_type":"code","execution_count":7,"metadata":{"executionInfo":{"elapsed":311,"status":"ok","timestamp":1717855661332,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"ttE11jTwh0-N"},"outputs":[],"source":["# 模型和数据路径都可以改成本地的\n","model_name_or_path = 'Qwen/Qwen1.5-0.5B'\n","data_name_or_path = 'bio-nlp-umass/bioinstruct'"]},{"cell_type":"code","execution_count":8,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":5190,"status":"ok","timestamp":1717855668328,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"myEJAVA4h0-N","outputId":"78a82b36-ba51-4afb-df81-c3f5bf48d89f"},"outputs":[{"name":"stderr","output_type":"stream","text":["/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_token.py:89: UserWarning: \n","The secret `HF_TOKEN` does not exist in your Colab secrets.\n","To authenticate with the Hugging Face Hub, create a token in your settings tab (https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session.\n","You will be able to reuse this secret in all of your notebooks.\n","Please note that authentication is recommended but still optional to access public models or datasets.\n","  warnings.warn(\n","Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.\n"]}],"source":["tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)\n","tokenizer.pad_token_id = tokenizer.eos_token_id\n","tokenizer.padding_side = 'left'\n","\n","model = AutoModelForCausalLM.from_pretrained(model_name_or_path, torch_dtype=dtype).to(device)"]},{"cell_type":"code","execution_count":9,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":2,"status":"ok","timestamp":1717855668328,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"UyJL36qJh0-N","outputId":"ecb6c261-c7a1-4376-a97a-d7fab62a60d6"},"outputs":[{"name":"stdout","output_type":"stream","text":["trainable params: 3,784,704 || all params: 467,772,416 || trainable%: 0.8091\n"]}],"source":["# 获取 lora model\n","replace_linear_with_lora(model, r=8, alpha=16, dropout_p=0.0)\n","model.to(device)\n","\n","# 查看可训练参数\n","print_trainable_parameters(model)"]},{"cell_type":"code","execution_count":10,"metadata":{"executionInfo":{"elapsed":449,"status":"ok","timestamp":1717855668776,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"jIgk3l64h0-N"},"outputs":[],"source":["# 定义训练数据集\n","class SFTDataset(Dataset):\n","    def __init__(self,\n","        tokenizer: AutoTokenizer,\n","        data_path: str,\n","        load_local: bool = False,\n","        max_len: int = 256,\n","        split_len: str = '1%',\n","    ):\n","        super().__init__()\n","        self.tokenizer = tokenizer\n","\n","        if load_local:\n","            ds = load_dataset('json', data_dir=data_path, split=f'train[:{split_len}]')\n","        else:\n","            ds = load_dataset(data_path, split=f'train[:{split_len}]')\n","        self.max_len = max_len\n","\n","        def process_func(example):\n","            # 提取 instruction 和 input\n","            instruction = example['instruction'].strip()\n","            input = example['input'].strip()\n","            output = example['output'].strip()\n","\n","            # 构造模板\n","            instruction_msg = [\n","                {\"role\": \"user\", \"content\": (instruction + f\"\\n{input}\") if len(input) > 0 else instruction}\n","            ]\n","            tokenized_instruction = tokenizer.apply_chat_template(instruction_msg, tokenize=True, add_generation_prompt=True)\n","            tokenized_output = tokenizer(output + \"<|im_end|>\" + f\"{tokenizer.eos_token}\\n\")['input_ids']\n","\n","            # 截断，最大不超过 max_len\n","            tokenized_prompt = (tokenized_instruction + tokenized_output)[:self.max_len]\n","\n","            # 构造 input_ids, attention_mask, labels\n","            input_ids = tokenized_prompt[:-1]\n","            padding_mask = ([0] * len(tokenized_instruction) + [1] * (len(tokenized_output)))[:self.max_len][1:]\n","            labels = tokenized_prompt[1:]\n","\n","            return {\n","                'input_ids': input_ids,\n","                'attention_mask': padding_mask,\n","                'labels': labels,\n","            }\n","\n","        self.ds = ds.map(\n","            process_func,\n","            batched=False,\n","            remove_columns=ds.column_names,\n","            desc='Processing dataset',\n","        )\n","\n","    def __len__(self):\n","        return len(self.ds)\n","\n","    def __getitem__(self, index: int):\n","        return self.ds[index]"]},{"cell_type":"code","execution_count":12,"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":49,"referenced_widgets":["04aafdc0432148f582ed087d2a1c633c","b9e3e8726f62484e91ba7a856f989e2b","0c658ef9486a468eaa3b26128210d35c","48358191065d4b57a5583e292cc13a5b","08216f16eb384f70a54e7fbb853237f5","32e099fc56274706ad350b9f521bb671","c4f5d662fd9a43cf87c1950435f04f0e","fcfc5ec17d644facab3ceecda8f47e8a","7207d40997084456b2e39c6e4ed5bb0b","3504d3f27b2d43fc8d2b56c65800be7e","5abe569a058348608ec7b6eda74945dc"]},"executionInfo":{"elapsed":3405,"status":"ok","timestamp":1717855681442,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"7-IO0KlFh0-N","outputId":"54d95cac-168a-41f8-a558-8fe20cb6104a"},"outputs":[{"data":{"application/vnd.jupyter.widget-view+json":{"model_id":"04aafdc0432148f582ed087d2a1c633c","version_major":2,"version_minor":0},"text/plain":["Processing dataset:   0%|          | 0/250 [00:00<?, ? examples/s]"]},"metadata":{},"output_type":"display_data"}],"source":["ds = SFTDataset(tokenizer, data_name_or_path, load_local=False)"]},{"cell_type":"code","execution_count":13,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":5597,"status":"ok","timestamp":1717855695742,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"n1Lbm02Kh0-N","outputId":"edf178b0-50f2-45cc-9ccc-a1557900877b"},"outputs":[{"name":"stdout","output_type":"stream","text":["79\n","79\n","79\n","<|im_start|>system\n","You are a helpful assistant<|im_end|>\n","<|im_start|>user\n","Identify the main conclusion from the provided medical report excerpt.\n","The patient's blood test results showed an elevation in liver enzymes, specifically ALT and AST, which suggests potential liver damage. Additionally, the patient's ultrasound showed a fatty liver.<|im_end|>\n","<|im_start|>assistant\n","The patient has signs of liver damage and a fatty liver.<|im_end|><|endoftext|>\n","[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\n","system\n","You are a helpful assistant<|im_end|>\n","<|im_start|>user\n","Identify the main conclusion from the provided medical report excerpt.\n","The patient's blood test results showed an elevation in liver enzymes, specifically ALT and AST, which suggests potential liver damage. Additionally, the patient's ultrasound showed a fatty liver.<|im_end|>\n","<|im_start|>assistant\n","The patient has signs of liver damage and a fatty liver.<|im_end|><|endoftext|>\n","\n"]}],"source":["print(len(ds[0]['input_ids']))\n","print(len(ds[0]['attention_mask']))\n","print(len(ds[0]['labels']))\n","\n","print(tokenizer.decode(ds[0]['input_ids']))\n","print(ds[0]['attention_mask'])\n","print(tokenizer.decode(ds[0]['labels']))"]},{"cell_type":"code","execution_count":14,"metadata":{"executionInfo":{"elapsed":1,"status":"ok","timestamp":1717855698415,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"xNYmfNt2h0-O"},"outputs":[],"source":["def collate_fn(batch: List, tokenizer):\n","    max_len = max(len(item['input_ids']) for item in batch)\n","\n","    input_ids = []\n","    attention_mask = []\n","    labels = []\n","\n","    for item in batch:\n","        input_id = item['input_ids']\n","        attention_mask_item = item['attention_mask']\n","        label = item['labels']\n","\n","        # 计算填充长度\n","        pad_len = max_len - len(input_id)\n","\n","        # 左填充\n","        input_ids.append([tokenizer.eos_token_id] * pad_len + input_id)\n","        attention_mask.append([0] * pad_len + attention_mask_item)\n","        labels.append([tokenizer.eos_token_id] * pad_len + label)\n","\n","    # 将列表转换为张量\n","    input_ids = torch.LongTensor(input_ids)\n","    attention_mask = torch.LongTensor(attention_mask)\n","    labels = torch.LongTensor(labels)\n","\n","    return {\n","        'input_ids': input_ids,\n","        'attention_mask': attention_mask,\n","        'labels': labels,\n","    }"]},{"cell_type":"code","execution_count":15,"metadata":{"executionInfo":{"elapsed":1,"status":"ok","timestamp":1717855699583,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"SZH6teYMh0-O"},"outputs":[],"source":["bsz = 8\n","lr = 5e-4\n","num_epochs = 3\n","logging_steps = 5\n","max_grad_norm = 1.0"]},{"cell_type":"code","execution_count":16,"metadata":{"executionInfo":{"elapsed":1,"status":"ok","timestamp":1717855700105,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"m7QYx_3th0-O"},"outputs":[],"source":["dataloader = DataLoader(ds, batch_size=bsz, shuffle=True, collate_fn=lambda batch: collate_fn(batch, tokenizer))"]},{"cell_type":"code","execution_count":17,"metadata":{"executionInfo":{"elapsed":2,"status":"ok","timestamp":1717855700537,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"T_soA9Xfh0-O"},"outputs":[],"source":["optimizer = optim.AdamW(model.parameters(), lr=lr)"]},{"cell_type":"code","execution_count":18,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":153822,"status":"ok","timestamp":1717855855315,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"UW9PxiAUh0-O","outputId":"33777159-577d-4d37-b672-8e86a2d5b62c"},"outputs":[{"name":"stderr","output_type":"stream","text":["Epoch 1/3:  12%|█▎        | 4/32 [00:08<00:56,  2.03s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 5/32, Loss: 2.0748, Grad Norm: 1.9531\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 1/3:  28%|██▊       | 9/32 [00:16<00:35,  1.56s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 10/32, Loss: 1.9878, Grad Norm: 1.7812\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 1/3:  44%|████▍     | 14/32 [00:24<00:31,  1.75s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 15/32, Loss: 1.9209, Grad Norm: 1.7109\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 1/3:  59%|█████▉    | 19/32 [00:33<00:23,  1.78s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 20/32, Loss: 1.9113, Grad Norm: 2.2188\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 1/3:  75%|███████▌  | 24/32 [00:41<00:12,  1.52s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 25/32, Loss: 1.8852, Grad Norm: 1.6406\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 1/3:  91%|█████████ | 29/32 [00:49<00:04,  1.65s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 30/32, Loss: 1.8730, Grad Norm: 1.9922\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 1/3: 100%|██████████| 32/32 [00:52<00:00,  1.64s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 1 finished, Average Loss: 1.8794\n"]},{"name":"stderr","output_type":"stream","text":["\n","Epoch 2/3:   6%|▋         | 2/32 [00:02<00:37,  1.25s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 3/32, Loss: 1.8285, Grad Norm: 1.3828\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/3:  22%|██▏       | 7/32 [00:10<00:41,  1.64s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 8/32, Loss: 1.7702, Grad Norm: 1.5156\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/3:  38%|███▊      | 12/32 [00:19<00:35,  1.78s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 13/32, Loss: 1.7095, Grad Norm: 1.5547\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/3:  53%|█████▎    | 17/32 [00:26<00:20,  1.40s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 18/32, Loss: 1.6636, Grad Norm: 1.9219\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/3:  69%|██████▉   | 22/32 [00:34<00:15,  1.57s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 23/32, Loss: 1.6245, Grad Norm: 1.5625\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/3:  84%|████████▍ | 27/32 [00:42<00:08,  1.64s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 28/32, Loss: 1.5951, Grad Norm: 1.4766\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 2/3: 100%|██████████| 32/32 [00:50<00:00,  1.57s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 2 finished, Average Loss: 1.5732\n"]},{"name":"stderr","output_type":"stream","text":["\n","Epoch 3/3:   0%|          | 0/32 [00:00<?, ?it/s]"]},{"name":"stdout","output_type":"stream","text":["Step: 1/32, Loss: 1.5647, Grad Norm: 1.8828\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/3:  16%|█▌        | 5/32 [00:08<00:43,  1.61s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 6/32, Loss: 1.5122, Grad Norm: 2.1094\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/3:  31%|███▏      | 10/32 [00:16<00:33,  1.54s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 11/32, Loss: 1.4668, Grad Norm: 2.2969\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/3:  47%|████▋     | 15/32 [00:25<00:29,  1.72s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 16/32, Loss: 1.4207, Grad Norm: 1.5234\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/3:  62%|██████▎   | 20/32 [00:33<00:20,  1.71s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 21/32, Loss: 1.3811, Grad Norm: 2.3906\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/3:  78%|███████▊  | 25/32 [00:41<00:11,  1.60s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 26/32, Loss: 1.3481, Grad Norm: 2.0625\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/3:  94%|█████████▍| 30/32 [00:48<00:03,  1.59s/it]"]},{"name":"stdout","output_type":"stream","text":["Step: 31/32, Loss: 1.3177, Grad Norm: 1.8594\n"]},{"name":"stderr","output_type":"stream","text":["Epoch 3/3: 100%|██████████| 32/32 [00:50<00:00,  1.59s/it]"]},{"name":"stdout","output_type":"stream","text":["Epoch 3 finished, Average Loss: 1.3119\n"]},{"name":"stderr","output_type":"stream","text":["\n"]}],"source":["model.train()\n","\n","total_loss = 0\n","total_step = 0\n","for epoch in range(num_epochs):\n","    for step, batch in enumerate(tqdm(dataloader, desc=f\"Epoch {epoch+1}/{num_epochs}\")):\n","        input_ids = batch['input_ids'].to(device)\n","        attention_mask = batch['attention_mask'].to(device)\n","        labels = batch['labels'].to(device)\n","\n","        optimizer.zero_grad()\n","        outputs = model(input_ids, attention_mask=attention_mask, labels=labels)\n","        logits = outputs.logits\n","        rearranged_logits = rearrange(logits, 'bsz seq_len vocab_size -> (bsz seq_len) vocab_size')\n","        rearranged_attention_mask = rearrange(attention_mask, 'bsz seq_len -> (bsz seq_len)')\n","        rearranged_labels = rearrange(labels, 'bsz seq_len -> (bsz seq_len)')\n","\n","        sum_loss = F.cross_entropy(rearranged_logits, rearranged_labels, ignore_index=0, reduction='none')\n","        loss = torch.sum(sum_loss * rearranged_attention_mask) / torch.sum(rearranged_attention_mask)\n","        loss.backward()\n","\n","        # 计算梯度范数并裁剪\n","        total_norm = nn.utils.clip_grad_norm_(model.parameters(), max_grad_norm)\n","\n","        optimizer.step()\n","        total_loss += loss.item()\n","\n","        total_step += 1\n","        if total_step % logging_steps == 0:\n","            avg_loss = total_loss / total_step\n","            print(f\"Step: {step+1}/{len(dataloader)}, Loss: {avg_loss:.4f}, Grad Norm: {total_norm:.4f}\", flush=True)\n","            # print(f\"Step: {step+1}/{len(dataloader)}, Loss: {avg_loss:.4f}\", flush=True)\n","\n","\n","    # 打印每个 epoch 结束的累计损失\n","    print(f\"Epoch {epoch+1} finished, Average Loss: {total_loss / total_step:.4f}\", flush=True)"]},{"cell_type":"code","execution_count":19,"metadata":{"executionInfo":{"elapsed":22,"status":"ok","timestamp":1717855855316,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"wthFVJ5W5H4t"},"outputs":[],"source":["def inference(\n","    model,\n","    tokenizer,\n","    text: str,\n","    max_new_tokens: int = 160,\n","    do_sample: bool = True,\n","    temperature: float = 0.3,\n","    print_inputs: bool = True,\n","    streaming: bool = False,\n","):\n","    # 构建输入\n","    prompt_msg = [\n","        {\"role\": \"user\", \"content\": text}\n","    ]\n","    prompt = tokenizer.apply_chat_template(prompt_msg, tokenize=False, add_generation_prompt=True)\n","    inputs = tokenizer(prompt, return_tensors='pt', add_special_tokens=False).to(device)\n","    input_ids = inputs['input_ids']\n","    im_end_id = tokenizer.encode(\"<|im_end|>\")[0]\n","\n","    # 是否打印输入部分\n","    if print_inputs:\n","        print(prompt, end='')\n","\n","    # 生成\n","    stop_words = [tokenizer.eos_token_id, im_end_id]\n","    generated_tokens = []\n","\n","    for _ in range(max_new_tokens):\n","        with torch.no_grad():\n","            outputs = model(input_ids)\n","\n","        logits = outputs.logits[:, -1, :]\n","\n","        # 不同采样方式\n","        if do_sample:\n","            logits = logits / temperature\n","            probs = F.softmax(logits, dim=-1)\n","            next_token = torch.multinomial(probs, num_samples=1)\n","        else:\n","            # 贪婪解码\n","            next_token = torch.argmax(logits, dim=-1, keepdim=True)\n","        if next_token.item() in stop_words:\n","            break\n","        generated_tokens.append(next_token.item())\n","        # 流式输出\n","        if streaming:\n","            yield tokenizer.decode(generated_tokens)\n","\n","        # 更新输入\n","        input_ids = torch.cat([input_ids, next_token], dim=-1)\n","\n","    generated_text = tokenizer.decode(generated_tokens)\n","    return generated_text"]},{"cell_type":"code","execution_count":20,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":38692,"status":"ok","timestamp":1717855894006,"user":{"displayName":"Zhang Max","userId":"16956753624958128646"},"user_tz":-480},"id":"ZycXHJ1Lh0-O","outputId":"db1db198-18ca-4d66-9563-a24d27f7d99d"},"outputs":[{"name":"stdout","output_type":"stream","text":["================================================================================\n","<|im_start|>system\n","You are a helpful assistant<|im_end|>\n","<|im_start|>user\n","Describe the process of bacterial conjugation and its significance in the context of antibiotic resistance.<|im_end|>\n","<|im_start|>assistant\n","Bacterial conjugation is a process by which bacteria exchange genetic material through direct cell-to-cell contact. This process plays a crucial role in antibiotic resistance as it allows bacteria to inherit the genes of other bacteria, increasing their ability to resist certain antibiotics. Conjugation occurs when two bacteria exchange genetic material through a process involving cell相亲、细胞融合和细胞质融合, resulting in new bacterial species with enhanced antibiotic resistance genes. This process contributes to the spread of antibiotic resistance among bacterial populations and ultimately contributes to the global pandemic of antibiotic-resistant bacteria.\n","\n","================================================================================\n","<|im_start|>system\n","You are a helpful assistant<|im_end|>\n","<|im_start|>user\n","Explain the role of insulin in the body and how insulin resistance affects blood sugar levels.<|im_end|>\n","<|im_start|>assistant\n","Insulin is a hormone produced by the pancreas that helps regulate blood sugar levels. Its main function is to transport glucose (sugar) from the bloodstream to cells, where it is used for energy or stored. Insulin resistance occurs when the body's cells do not respond properly to insulin, leading to a decrease in insulin sensitivity and an increase in glucose production. This can result in higher blood sugar levels, which can lead to a range of health problems, including cardiovascular disease, diabetes, and some cancers. Insulin resistance can also contribute to the development of type 2 diabetes.\n","\n","================================================================================\n","<|im_start|>system\n","You are a helpful assistant<|im_end|>\n","<|im_start|>user\n","Provide recommendations for lifestyle changes that can help improve the overall health of a patient with type 2 diabetes.<|im_end|>\n","<|im_start|>assistant\n","1. Maintain a healthy diet: Eat a balanced diet with lean protein, whole grains, fruits, vegetables, and healthy fats. Limit consumption of sugary beverages, processed foods, and saturated fats.\n","2. Exercise regularly: Aim for at least 150 minutes of moderate-intensity exercise per week, such as walking, swimming, or biking. Consult with a healthcare professional to determine the appropriate exercise regimen.\n","3. Maintain a healthy weight: Focus on making healthy lifestyle choices and being mindful of portion sizes. Consult with a healthcare professional to determine the appropriate weight range for your patient.\n","4. Limit alcohol intake: Limit alcohol intake to no more than 150 ml per day, and consider limiting alcohol consumption while on medication.\n","5. Manage stress: Practice stress management techniques like deep breathing\n","\n"]}],"source":["model.eval()\n","\n","for test_text in [\n","    'Describe the process of bacterial conjugation and its significance in the context of antibiotic resistance.',\n","    'Explain the role of insulin in the body and how insulin resistance affects blood sugar levels.',\n","    'Provide recommendations for lifestyle changes that can help improve the overall health of a patient with type 2 diabetes.',\n","]:\n","    print('=' * 80)\n","    last_text = ''\n","    for text in inference(model, tokenizer, test_text, streaming=True):\n","        cur_text = text.replace(last_text, '')\n","        print(cur_text, end='', flush=True)\n","        last_text = text\n","    print('\\n')"]},{"cell_type":"code","execution_count":null,"metadata":{"id":"SOQR_qyaLgx1"},"outputs":[],"source":[]}],"metadata":{"accelerator":"GPU","colab":{"collapsed_sections":["SjXs_dE2Af7F"],"gpuType":"T4","provenance":[]},"kernelspec":{"display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.6"},"widgets":{"application/vnd.jupyter.widget-state+json":{"04aafdc0432148f582ed087d2a1c633c":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_b9e3e8726f62484e91ba7a856f989e2b","IPY_MODEL_0c658ef9486a468eaa3b26128210d35c","IPY_MODEL_48358191065d4b57a5583e292cc13a5b"],"layout":"IPY_MODEL_08216f16eb384f70a54e7fbb853237f5"}},"08216f16eb384f70a54e7fbb853237f5":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"0c658ef9486a468eaa3b26128210d35c":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_fcfc5ec17d644facab3ceecda8f47e8a","max":250,"min":0,"orientation":"horizontal","style":"IPY_MODEL_7207d40997084456b2e39c6e4ed5bb0b","value":250}},"32e099fc56274706ad350b9f521bb671":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"3504d3f27b2d43fc8d2b56c65800be7e":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"48358191065d4b57a5583e292cc13a5b":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_3504d3f27b2d43fc8d2b56c65800be7e","placeholder":"​","style":"IPY_MODEL_5abe569a058348608ec7b6eda74945dc","value":" 250/250 [00:01&lt;00:00, 260.81 examples/s]"}},"4ccf232c866741629efcbe1b5ba9a351":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_75d2ff5b765d4995a11b4089567c5721","IPY_MODEL_55bea771ee224309b67f1ec9c510a1b3","IPY_MODEL_923de34852dd49019e6371513e3c388e"],"layout":"IPY_MODEL_6bc07c55b4ef4178a516d67575837d3d"}},"55bea771ee224309b67f1ec9c510a1b3":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"FloatProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"FloatProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_b8b335af500b41c78d2600647dc53fde","max":520,"min":0,"orientation":"horizontal","style":"IPY_MODEL_65150a18fadf41be9f13cfbf16e9b7ae","value":520}},"5abe569a058348608ec7b6eda74945dc":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"65150a18fadf41be9f13cfbf16e9b7ae":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"6bc07c55b4ef4178a516d67575837d3d":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"7207d40997084456b2e39c6e4ed5bb0b":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"75d2ff5b765d4995a11b4089567c5721":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_cc40a7b1c3e947d5b10cb9636eb97ce4","placeholder":"​","style":"IPY_MODEL_d0585f8782424e7c9637331bab77f0eb","value":"Processing dataset: 100%"}},"923de34852dd49019e6371513e3c388e":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_de99652a1377422eba4647196205fa6a","placeholder":"​","style":"IPY_MODEL_f7d3a0447f054bbabc79ffbfb175e534","value":" 520/520 [00:00&lt;00:00, 656.23 examples/s]"}},"b8b335af500b41c78d2600647dc53fde":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"b9e3e8726f62484e91ba7a856f989e2b":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_32e099fc56274706ad350b9f521bb671","placeholder":"​","style":"IPY_MODEL_c4f5d662fd9a43cf87c1950435f04f0e","value":"Processing dataset: 100%"}},"c4f5d662fd9a43cf87c1950435f04f0e":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"cc40a7b1c3e947d5b10cb9636eb97ce4":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"d0585f8782424e7c9637331bab77f0eb":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"de99652a1377422eba4647196205fa6a":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"f7d3a0447f054bbabc79ffbfb175e534":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"fcfc5ec17d644facab3ceecda8f47e8a":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}}}}},"nbformat":4,"nbformat_minor":0}
